package com.jtw.conf.shiro;

import com.jtw.conf.shiro.enums.LoginType;
import com.jtw.conf.shiro.enums.UserState;
import com.jtw.conf.shiro.model.BaseRole;
import com.jtw.conf.shiro.model.BaseUser;
import com.jtw.conf.shiro.service.BasePermService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import java.util.HashSet;
import java.util.Set;


/**
 * DESCRIPT: 通用自定义shiro realm权限过滤
 *
 * @author cjsky666
 * @date 2018-8-30 10:38
 */
@Slf4j
public class CustomAuthorizingRealm extends AuthorizingRealm {

    @Lazy
    @Autowired
    BasePermService basePermService;

    /**
     * 权限校验
     * @param principalCollection
     * @return
     * @desc 自定义权限校验器之后。此默认权限校验不再调用
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("权限校验开始");
        String username = (String) principalCollection.getPrimaryPrincipal();
        // 根据用户名查询当前用户拥有的角色
        Set<BaseRole> authRoles = basePermService.getRolesByUserName(username);
        Set<String> roleNames = new HashSet<>();
        for (BaseRole baseRole : authRoles) {
            roleNames.add(baseRole.getId().toString());
        }
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        // 将角色名称提供给info
        authorizationInfo.setRoles(roleNames);
        return authorizationInfo;
    }


    /**
     * 登录校验
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("登录校验开始");
        CustomTypeToken token = (CustomTypeToken) authenticationToken;
        String userName = (String) token.getPrincipal();
        BaseUser user=null;
        if(token.getType().equals(LoginType.PASSWORD)||token.getType().equals(LoginType.NOPASSWD)){
            user = basePermService.getUserByUserName(userName);
        }else if(token.getType().equals(LoginType.MOBILE)) {
            user = basePermService.getUserByMobile(userName);
        }else if(token.getType().equals(LoginType.WXAPP)){
            user = basePermService.getUserByWXAPP(userName);
        }else if(token.getType().equals(LoginType.WXGZH)){
            user = basePermService.getUserByWXGZH(userName);
        }else if(token.getType().equals(LoginType.TX_UNION)){
            user = basePermService.getUserByTXUNION(userName);
        }else if(token.getType().equals(LoginType.ZFB)){
            user = basePermService.getUserByZFB(userName);
        }else if(token.getType().equals(LoginType.QQ)){
            user = basePermService.getUserByQQ(userName);
        }else if(token.getType().equals(LoginType.SINA)){
            user = basePermService.getUserBySina(userName);
        }
        if(user == null){
            //未找到用户
            throw new UnknownAccountException();
        }
        if(user.getState() == UserState.Lock.getState()){
            //用户已被锁定
            throw new LockedAccountException();
        }
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                user.getUserName(),
                user.getPassword(),
                ByteSource.Util.bytes(user.getSalt()),
                getName());
        return simpleAuthenticationInfo;
    }
}
